
from typing import Any, Dict
from ddgs import DDGS
import trafilatura
from concurrent.futures import ThreadPoolExecutor, as_completed
import primp
import logging
logger = logging.getLogger(__name__)

from .base_tool import BaseTool, ToolResult


class DdgsSearchTool(BaseTool):
    """Tool for searching the web using various search APIs."""

    def __init__(self):
        super().__init__(
            name="web_search",
            description=self._get_detailed_description()
        )

    def _get_detailed_description(self) -> str:
        """Get detailed description with examples for web search operations."""
        #         return """Search the web for current information, news, and real-time data using advanced search APIs.
        #
        # WHAT IT DOES:
        # • Searches the internet for up-to-date information
        # • Returns relevant web pages, articles, and resources
        # • Provides real-time data and current events
        # • Finds information not available in static databases
        #
        # SEARCH TYPES:
        # • General Search: Find web pages, articles, documentation
        #   Examples: "latest AI developments", "Python programming tutorial"
        #
        # • News Search: Current events, breaking news, recent updates
        #   Examples: "today's news", "stock market updates", "weather forecast"
        #
        # • Technical Information: Documentation, APIs, code examples
        #   Examples: "React hooks documentation", "MySQL syntax guide"
        #
        # • Product Information: Reviews, comparisons, specifications
        #   Examples: "iPhone 15 review", "best laptops 2024"
        #
        # BEST USE CASES:
        # • Current events and breaking news
        # • Real-time data (stock prices, weather, sports scores)
        # • Recent developments in technology, science, politics
        # • Product reviews and comparisons
        # • Technical documentation and tutorials
        # • Finding specific websites or resources
        #
        # USAGE EXAMPLES:
        # - Current events: "Ukraine war latest news"
        # - Technical info: "Docker compose tutorial"
        # - Product research: "best electric cars 2024"
        # - Real-time data: "Bitcoin price today"
        # - Specific searches: "OpenAI GPT-4 capabilities"
        #
        # SEARCH STRATEGIES:
        # • Use specific keywords for better results
        # • Include time indicators for recent info ("2024", "latest", "recent")
        # • Use quotes for exact phrases: "climate change effects"
        # • Add context for ambiguous terms
        # • Combine multiple relevant keywords
        #
        # RETURNED INFORMATION:
        # - Page titles and descriptions
        # - URLs for full articles
        # - Publication dates when available
        # - Relevance rankings
        # - Related search suggestions
        #
        # ADVANTAGES OVER OTHER TOOLS:
        # • More current than Wikipedia
        # • Broader coverage than academic databases
        # • Real-time information updates
        # • Access to diverse sources and perspectives
        # • Technical documentation and tutorials"""

        return """使用高级搜索API搜索网络上的当前信息、新闻和实时数据。

功能：
- 在互联网上搜索最新信息
- 返回相关网页、文章和资源
- 提供实时数据和时事
- 查找静态数据库中没有的信息

搜索类型：
- 通用搜索：查找网页、文章、文档
  示例：“最新人工智能发展”、“Python编程教程”

- 新闻搜索：时事、突发新闻、最新更新
  示例：“今日新闻”、“股市更新”、“天气预报”

- 技术信息：文档、API、代码示例
  示例：“React钩子文档”、“MySQL语法指南”

- 产品信息：评论、比较、规格
  示例：“iPhone 15评测”、“2024年最佳笔记本电脑”

最佳使用场景：
- 时事和突发新闻
- 实时数据（股票价格、天气、体育比分）
- 技术、科学、政治领域的最新发展
- 产品评论和比较
- 技术文档和教程
- 查找特定网站或资源

使用示例：
- 时事：“乌克兰战争最新消息”
- 技术信息：“Docker compose教程”
- 产品研究：“2024年最佳电动汽车”
- 实时数据：“今日比特币价格”
- 特定搜索：“OpenAI GPT-4功能”

搜索策略：
- 使用特定关键词以获得更好的结果
- 包含时间指示词以获取近期信息（“2024年”、“最新”、“最近”）
- 对确切短语使用引号：“气候变化影响”
- 为模糊术语添加上下文
- 组合多个相关关键词

返回的信息：
- 页面标题和描述
- 完整文章的URL
- 内容
- 得分

相对于其他工具的优势：
- 比维基百科更及时
- 比学术数据库覆盖范围更广
- 实时信息更新
- 可获取多样化的来源和观点
- 技术文档和教程"""

    async def execute(self, query: str, **kwargs) -> ToolResult:
        """Execute web search."""
        try:
            # Get optional parameters
            max_results = kwargs.get("max_results", 10)

            return await self._search_with_ddgs(query, max_results)

        except Exception as e:
            return ToolResult(
                success=False,
                data=None,
                error=f"Web search failed: {str(e)}"
            )

    async def _search_with_ddgs(self, query: str, max_results: int) -> ToolResult:
        """Search using Serper API."""
        try:
            tool = DDGS()
            results = tool.text(query=query, region='cn-zh', max_results=max_results)

            fixed_result = []
            with ThreadPoolExecutor(max_workers=len(results)) as executor:
                futures = []
                for i, item in enumerate(results, start=1):
                    f = executor.submit(self.extract_text, item, False)
                    futures.append(f)

                for future in as_completed(futures):
                    if future.exception() is not None:
                        continue
                    res = future.result()
                    if res is not None:
                        fixed_result.append(res)

            return ToolResult(
                success=True,
                data={
                    "query": query,
                    "results": fixed_result,
                    "total_results": len(fixed_result)
                },
                metadata={
                    "max_results": max_results,
                    "provider": "ddgs"
                }
            )
        except Exception as e:
            return ToolResult(
                success=False,
                data=None,
                error=f"DDGS search failed: {str(e)}"
            )

    @staticmethod
    def extract_text(item: dict, verify: bool = False) -> dict | None:
        resp = primp.Client(
            impersonate="random", impersonate_os="random", timeout=10, verify=verify
        ).get(item.get('href'))

        if resp.status_code == 200:
            item['body'] = trafilatura.extract(resp.text)
            return item

    def get_schema(self) -> Dict[str, Any]:
        """Get the tool's input schema."""
        # return {
        #     "type": "object",
        #     "properties": {
        #         "query": {
        #             "type": "string",
        #             "description": "Search query to find information on the web"
        #         },
        #         "num_results": {
        #             "type": "integer",
        #             "description": "Number of search results to return (default: 5)",
        #             "default": 5,
        #             "minimum": 1,
        #             "maximum": 20
        #         },
        #         "search_type": {
        #             "type": "string",
        #             "description": "Type of search to perform",
        #             "enum": ["search", "news", "images"],
        #             "default": "search"
        #         }
        #     },
        #     "required": ["query"]
        # }

        return {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "用于网络信息检索的查询语句"
                },
                "max_results": {
                    "type": "integer",
                    "description": "要返回的搜索结果数量（默认值：5）",
                    "default": 5,
                    "minimum": 1,
                    "maximum": 20
                }
            },
            "required": ["query"]
        }